home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include "diadef.h"
- #include "dialog.h"
- #include "internal.h"
-
- /*
- Evaluate the size of a text in a string.
- (number of line, maximum width)
-
- The string may contain tabs.
- Return the number of line
- */
- int dialog_textsize (const char *txt, int *width)
- {
- int nbline=1;
- int maxlen = 0;
- if (txt != NULL){
- const char *lastpt = txt;
- char *pt = strchr (txt,'\n');
- while (pt != NULL){
- int len = 0;
- while (lastpt < pt){
- if (*lastpt == '\t'){
- if (len % 8 == 0) len++;
- while (len % 8 != 0) len++;
- }else{
- len++;
- }
- lastpt++;
- }
- len += 2;
- nbline++;
- if (len > maxlen) maxlen = len;
- lastpt = pt+1;
- pt = strchr (lastpt,'\n');
- }
- {
- int lastlen = strlen (lastpt);
- if (lastlen > maxlen) maxlen = lastlen;
- }
- }
- *width = maxlen;
- return nbline;
- }
-
- /*
- Open a centered window
- */
- WINDOW *dialog_openwin(
- int height,
- int width)
- {
- WINDOW *dialog;
- if (COLS == 0){
- fprintf (stderr,"You forget init_dialog\n");
- exit (-1);
- }else{
- /* center dialog box on screen */
- int x = (COLS - width)/2;
- int y = (LINES - height)/2;
- // Open larger to draw the shadow
- int height_1 = height+1;
- if (height_1 > LINES) height_1 = LINES;
- int width_2 = width+2;
- if (width_2 > COLS) width_2 = COLS;
- dialog = newwin(height_1, width_2, y, x);
- keypad(dialog, TRUE);
- }
- return dialog;
- }
-
- void dialog_draw (
- WINDOW *dialog,
- const char *title,
- const char *intro,
- int height,
- int width)
- {
- draw_box(dialog, 0, 0, height, width, dialog_attr
- , border_attr, border_attr_shadow);
- draw_shadow(dialog, 0, 0, height, width);
-
- if (title != NULL) {
- wattrset(dialog, title_attr);
- wmove(dialog, 0, (width - strlen(title))/2 - 1);
- waddch(dialog, ' ');
- waddstr(dialog, (char*)title);
- waddch(dialog, ' ');
- }
- if (intro != NULL){
- int posy = 1;
- while (*intro != '\0'){
- char tmp[100];
- char *pt = tmp;
- while (*intro != '\0' && *intro != '\n'){
- *pt++ = *intro++;
- }
- *pt = '\0';
- if (*intro == '\n') intro++;
- wmove (dialog,posy++,2);
- waddstr (dialog,tmp);
- }
- }
- }
-
- /*
- Compute the layout of the dialog based on its content.
- */
- PRIVATE void DIALOG::setup ()
- {
- int fields_height = getnb()==0 ? 0 : getnb()+2;
- int button_height = 3;
- int frame_space = 3;
- int max_prompt = 0;
- int intro_height= 0;
- int intro_width = 0;
- if (!intro.is_empty()){
- intro_height = dialog_textsize(intro.get(),&intro_width);
- intro_width += 4;
- }
- nbvisible = getnb();
- height = intro_height + frame_space + button_height + fields_height;
- if (height > 24){
- nbvisible -= height - 24;
- height = 24;
- }
- int max_field = 0;
- for (int i=0; i<getnb(); i++){
- FIELD *f = getitem(i);
- char *prompt = f->prompt;
- int len = strlen(prompt);
- if (len > max_prompt) max_prompt = len;
- f->box.y = 3 + intro_height + i - offset;
- if (max_field < f->box.width) max_field = f->box.width;
- }
- int data_width = max_field + 5 + max_prompt;
- width = data_width;
- if (width < intro_width) width = intro_width;
- int title_len = title.getlen();
- int button_len = buttons->evalwidth();
- if (title_len > width) width = title_len;
- if (button_len > width) width = button_len;
- buttons->setup (height-3,width);
- // Try to center the data box if there is no prompt
- if (data_width < width && max_prompt < 2){
- max_prompt += (width - data_width)/2;
- }
- for (i=0; i<getnb(); i++){
- FIELD *f = getitem(i);
- f->box.x = max_prompt + 3;
- f->box.width = max_field;
- }
- }
-
- /*
- Set the offset of the first visible field and ajust
- the coordinate of all field so they will know where to draw
- themselve.
- */
- PRIVATE void DIALOG::setoffset (int newoff)
- {
- int diff = newoff - offset;
- offset = newoff;
- for (int i=0; i<getnb(); i++){
- getitem(i)->box.y -= diff;
- }
- }
-
- /*
- Draw all visible field
- */
- PROTECTED void DIALOG::drawf(WINDOW *dialog)
- {
- int lastf = getnb();
- if (lastf - offset > nbvisible) lastf = offset + nbvisible;
- for (int i=offset; i<lastf; i++){
- getitem(i)->draw (dialog);
- }
- }
- /*
- Send a message to all fields of a dialog
- */
- PRIVATE void DIALOG::processmsg(WINDOW *dialog, FIELD_MSG &msg)
- {
- int lastf = getnb();
- int last_visible = offset + nbvisible;
- for (int i=0; i<lastf; i++){
- getitem(i)->processmsg (dialog,msg
- ,i >= offset && i < last_visible);
- }
- }
- /*
- Draw the complete dialog
- */
-
- PRIVATE void DIALOG::draw (WINDOW *dialog)
- {
- dialog_draw (dialog,title.get(),intro.get(),height,width);
- wattrset(dialog, dialog_attr);
- if (getnb()>0){
- /* Draw the input field box */
- FIELD *finfo = getitem(offset);
- draw_box(dialog, finfo->box.y-1, finfo->box.x-1, nbvisible+2
- , finfo->box.width+2
- , inputbox_attr, border_attr_shadow,border_attr);
- drawf(dialog);
- }
- buttons->draw (dialog,button);
- }
- PRIVATE void DIALOG::drawarrow_if(
- WINDOW *win,
- bool condition, // Should it be drawn
- bool & flag, // Does the carac is already drawn
- bool top, // Top or bottom arrow
- chtype carac) // Char to print
- {
- if (getnb() > 0){
- FIELD *f = getitem(offset);
- int posx = f->box.x + f->box.width/2;
- int posy = top ? f->box.y - 1 : f->box.y + nbvisible;
- if (condition){
- if (!flag){
- flag = true;
- wmove (win,posy,posx);
- wattrset(win,inputbox_border_attr);
- waddch (win,carac);
- }
- }else if (flag){
- flag = false;
- wmove (win,posy,posx);
- wattrset(win,inputbox_border_attr);
- waddch (win,ACS_HLINE);
- }
- }
- }
-
- /*
- Interpret a cursor key.
- Return -1 if it not a cursor key
- */
- PROTECTED VIRTUAL int DIALOG::keymove (WINDOW *dialog, int key, int &nof)
- {
- int ret = 0;
- switch (key){
- case KEY_PPAGE:
- if (offset == 0){
- nof = 0;
- }else{
- int newoff = offset - nbvisible;
- if (newoff < 0) newoff = 0;
- nof -= (offset - newoff);
- setoffset(newoff);
- drawf(dialog);
- }
- break;
- case KEY_UP:
- nof--;
- if (nof < offset){
- if (offset > 0){
- setoffset(offset -1);
- drawf(dialog);
- }else{
- nof = 0;
- }
- }
- break;
- case KEY_NPAGE:
- {
- int maxoffset = getnb() - nbvisible;
- if (maxoffset < 0) maxoffset = 0;
- if (offset >= maxoffset){
- nof = getnb()-1;
- }else{
- int newoff = offset + nbvisible;
- if (newoff > maxoffset) newoff = maxoffset;
- nof += (newoff - offset);
- setoffset(newoff);
- drawf(dialog);
- }
- }
- break;
- case KEY_DOWN:
- nof++;
- if (nof < getnb()){
- if (nof == offset + nbvisible){
- setoffset (offset+1);
- drawf(dialog);
- }
- }else{
- nof--;
- }
- break;
- default:
- ret = -1;
- }
- return ret;
- }
- DIALOG_MODE dialog_mode = DIALOG_CURSES;
- /*
- Set the basic user interface mode.
- This function is generally called at startup time
- */
- void dialog_setmode (DIALOG_MODE mode)
- {
- dialog_mode = mode;
- }
-
- PUBLIC DIALOG::DIALOG()
- {
- buttons = new BUTTONS_INFO;
- offset = 0;
- }
- PUBLIC DIALOG::~DIALOG()
- {
- html_forgetdialog (this);
- delete buttons;
- }
- /*
- Multiple field dialog.
- All field are shown one under each others
- */
- PUBLIC MENU_STATUS DIALOG::edit(
- const char *_title, // Main title
- const char *_intro, // Mini help describing the purpose
- // of the dialog
- const char *helpfile, // Help text in a file or NULL
- int &nof, // Start editing on which field
- // Will contain the current field.
- int but_options) // MENUBUT_xxxxx
- {
- MENU_STATUS ret = MENU_NULL;
- button = getnb()==0 ? 0 : -1; // Button currently selected
- title.setfrom (_title);
- intro.setfrom (_intro);
- buttons->set (but_options,helpfile);
- setup ();
-
- if (dialog_mode == DIALOG_HTML){
- ret = edithtml (nof);
- }else{
- ret = editterm (nof,but_options);
- }
- if (ret == MENU_ACCEPT){
- /* Save the content of the edit field into the buffer */
- save();
- }
- return ret;
- }
- /*
- Multiple field dialog.
- All field are shown one under each others
- */
- PUBLIC MENU_STATUS DIALOG::edit(
- const char *_title, // Main title
- const char *_intro, // Mini help describing the purpose
- // of the dialog
- HELP_FILE &helpfile, // Help text in a file or NULL
- int &nof, // Start editing on which field
- // Will contain the current field.
- int but_options) // MENUBUT_xxxxx
- {
- return edit (_title,_intro,helpfile.getpath(),nof,but_options);
- }
-
- /*
- Multiple field dialog.
- All field are shown one under each others
- */
- PUBLIC MENU_STATUS DIALOG::edit(
- const char *_title, // Main title
- const char *intro, // Mini help describing the purpose
- // of the dialog
- const char *helpfile, // Help text in a file or NULL
- int nof) // Start editing on which field
- {
- return edit (_title,intro,helpfile,nof
- ,MENUBUT_ACCEPT|MENUBUT_CANCEL);
- }
-
- /*
- Multiple field dialog.
- All field are shown one under each others
- */
- PUBLIC MENU_STATUS DIALOG::edit(
- const char *_title, // Main title
- const char *intro, // Mini help describing the purpose
- // of the dialog
- HELP_FILE &helpfile, // Help text in a file or NULL
- int nof) // Start editing on which field
- {
- return edit (_title,intro,helpfile.getpath(),nof);
- }
-
-
- #ifdef TEST
-
- #include "../translate/translat.h"
-
- int main (int argc, char *argv[])
- {
- translat_load ("/tmp","linuxconf-msg-" REVISION ".eng");
- init_dialog();
- DIALOG dia;
- char str1[80]; str1[0] = '\0';
- char str2[100]; strcpy (str2,"Hello");
- SSTRING pass;
- char addr[10]; addr[0] = '\0';
- dia.newf_str ("Question 1",str1,sizeof(str1)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- char chk = 0;
- dia.newf_chk ("Option",chk,"more option");
- dia.newf_pass ("Password",pass);
- dia.newf_str ("Address",addr,sizeof(addr)-1);
- SSTRING addr2;
- FIELD_COMBO *comb = dia.newf_combo ("Combo",addr2);
- comb->addopt("opt 1");
- comb->addopt("opt 2");
- comb->addopt("opt 3");
- comb->addopt("opt 4");
- SSTRING addr3;
- dia.newf_str ("sstring",addr3);
- dia.edit ("This is a test",NULL,NULL,0);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dia.newf_str ("Other",str2,sizeof(str2)-1);
- dialog_settimeout (15,MENU_ESCAPE,1);
- dia.edit ("This is a test"
- ,"Please you must reenter the\n"
- "value\n"
- "or accept it\n"
- ,"helpfile"
- ,2);
- endwin();
- printf ("Question 1 :%s:\n",str1);
- printf ("Other :%s:\n",str2);
- printf ("Option :%s:\n",chk ? "Selected" : "Not selected");
- printf ("Password :%s:\n",pass.get());
- printf ("Address :%s:\n",addr);
- printf ("Address 2 :%s:\n",addr2.get());
- printf ("Address 3 :%s:\n",addr3.get());
- return 0;
- }
-
- #endif
-
-